package controller

import (
	admin "gitee.com/kordar/goadmin/admin/form"
	"github.com/gin-gonic/gin"
	"github.com/kordar/ginsys/util"
	response "github.com/kordar/goframework_resp"
	"github.com/kordar/gorbac"
	"github.com/spf13/cast"
)

type RbacController struct {
	service *gorbac.RbacService
}

func NewRbacController(service *gorbac.RbacService) *RbacController {
	return &RbacController{service}
}

func (c RbacController) AddPermissionChildren(ctx *gin.Context) {
	f := admin.AddPermissionChildrenForm{}
	if err := util.DefaultGetValidParams(ctx, &f); err != nil {
		response.Error(ctx, err, nil)
		return
	}
	c.service.CleanChildren(f.Name)

	_ = c.service.AssignChildren(f.Name, f.Children...)
	response.Success(ctx, "success", nil)
}

func (c RbacController) GetChildren(ctx *gin.Context) {
	name, _ := ctx.GetQuery("name")
	children := c.service.GetChildren(name)
	response.Success(ctx, "", children)
}

func (c RbacController) Roles(ctx *gin.Context) {
	roles := c.service.Roles()
	response.Data(ctx, "", roles, int64(len(roles)))
}

func (c RbacController) GetRolesByUser(ctx *gin.Context) {
	id, _ := ctx.GetQuery("id")
	userId := cast.ToInt64(id)
	roles := c.service.GetRolesByUser(userId)
	response.Data(ctx, "", roles, int64(len(roles)))
}

func (c RbacController) AssignItemToUser(ctx *gin.Context) {
	f := admin.AssignItemForm{}
	if err := util.DefaultGetValidParams(ctx, &f); err != nil {
		response.Error(ctx, err, nil)
		return
	}

	c.service.Assigns(f.Id, f.Roles...)
	c.service.Assigns(f.Id, f.Permissions...)
	response.Success(ctx, "success", nil)
}

func (c RbacController) AddRole(ctx *gin.Context) {
	f := admin.RoleForm{}
	if err := util.DefaultGetValidParams(ctx, &f); err != nil {
		response.Error(ctx, err, nil)
		return
	}

	flag := c.service.AddRole(f.Name, f.Description, f.RuleName)
	response.SuccessOrError(ctx, flag, "success", "fail")
}

func (c RbacController) UpdateRole(ctx *gin.Context) {
	f := admin.UpdateRoleForm{}
	if err := util.DefaultGetValidParams(ctx, &f); err != nil {
		response.Error(ctx, err, nil)
		return
	}

	flag := c.service.UpdateRole(f.SourceName, f.TargetName, f.Description, f.RuleName)
	response.SuccessOrError(ctx, flag, "success", "fail")
}

func (c RbacController) DeleteRole(ctx *gin.Context) {
	f := admin.RoleForm{}
	if err := util.DefaultGetValidParams(ctx, &f); err != nil {
		response.Error(ctx, err, nil)
		return
	}

	flag := c.service.DeleteRole(f.Name)
	response.SuccessOrError(ctx, flag, "success", "fail")
}

func (c RbacController) BatchDeleteRoles(ctx *gin.Context) {
	f := admin.BatchItemsForm{}
	if err := util.DefaultGetValidParams(ctx, &f); err != nil {
		response.Error(ctx, err, nil)
		return
	}

	for _, name := range f.Names {
		c.service.DeleteRole(name)
	}
	response.Success(ctx, "success", nil)
}

func (c RbacController) Permissions(ctx *gin.Context) {
	permissions := c.service.Permissions()
	response.Data(ctx, "", permissions, int64(len(permissions)))
}

func (c RbacController) GetPermissionsByUser(ctx *gin.Context) {
	id, _ := ctx.GetQuery("id")
	//admin := ctx.MustGet(enums.AdminKey).(models.Admin)
	userId := cast.ToInt64(id)
	permissions := c.service.GetPermissionsByUser(userId)
	response.Data(ctx, "", permissions, int64(len(permissions)))
}

func (c RbacController) AddPermission(ctx *gin.Context) {
	f := admin.PermissionForm{}
	if err := util.DefaultGetValidParams(ctx, &f); err != nil {
		response.Error(ctx, err, nil)
		return
	}

	flag := c.service.AddPermission(f.Name, f.Description, f.RuleName)
	response.SuccessOrError(ctx, flag, "success", "fail")
}

func (c RbacController) UpdatePermission(ctx *gin.Context) {
	f := admin.UpdatePermissionForm{}
	if err := util.DefaultGetValidParams(ctx, &f); err != nil {
		response.Error(ctx, err, nil)
		return
	}

	flag := c.service.UpdatePermission(f.SourceName, f.TargetName, f.Description, f.RuleName)
	response.SuccessOrError(ctx, flag, "success", "fail")
}

func (c RbacController) DeletePermission(ctx *gin.Context) {
	f := admin.PermissionForm{}
	if err := util.DefaultGetValidParams(ctx, &f); err != nil {
		response.Error(ctx, err, nil)
		return
	}

	flag := c.service.DeletePermission(f.Name)
	response.SuccessOrError(ctx, flag, "success", "fail")
}

func (c RbacController) BatchDeletePermissions(ctx *gin.Context) {
	f := admin.BatchItemsForm{}
	if err := util.DefaultGetValidParams(ctx, &f); err != nil {
		response.Error(ctx, err, nil)
		return
	}

	for _, name := range f.Names {
		c.service.DeletePermission(name)
	}
	response.Success(ctx, "success", nil)
}

func (c RbacController) FastAddPermission(ctx *gin.Context) {
	f := admin.FastAddPermissionForm{}
	if err := util.DefaultGetValidParams(ctx, &f); err != nil {
		response.Error(ctx, err, nil)
		return
	}

	c.service.AddPermission("/resource/"+f.Resource+"/add", f.Name+"-Add", "")
	c.service.AddPermission("/resource/"+f.Resource+"/update", f.Name+"-Update", "")
	c.service.AddPermission("/resource/"+f.Resource+"/configs", f.Name+"-Configs", "")
	c.service.AddPermission("/resource/"+f.Resource+"/delete", f.Name+"-Delete", "")
	c.service.AddPermission("/resource/"+f.Resource+"/edit", f.Name+"-Edit", "")
	c.service.AddPermission("/resource/"+f.Resource+"/info", f.Name+"-Info", "")
	c.service.AddPermission("/resource/"+f.Resource+"/list", f.Name+"-List", "")
	c.service.AddPermission("/resource/"+f.Resource+"/output", f.Name+"-Output", "")
	response.Success(ctx, "success", nil)
}

func (c RbacController) Rules(ctx *gin.Context) {
	rules := c.service.Rules()
	response.Data(ctx, "", rules, int64(len(rules)))
}

func (c RbacController) AddRule(ctx *gin.Context) {
	f := admin.RuleForm{}
	if err := util.DefaultGetValidParams(ctx, &f); err != nil {
		response.Error(ctx, err, nil)
		return
	}

	flag := c.service.AddRule(f.Name, f.ExecuteName)
	response.SuccessOrError(ctx, flag, "success", "fail")
}

func (c RbacController) UpdateRule(ctx *gin.Context) {
	f := admin.UpdateRuleForm{}
	if err := util.DefaultGetValidParams(ctx, &f); err != nil {
		response.Error(ctx, err, nil)
		return
	}

	flag := c.service.UpdateRule(f.SourceName, f.TargetName, f.ExecuteName)
	response.SuccessOrError(ctx, flag, "success", "fail")
}

func (c RbacController) DeleteRule(ctx *gin.Context) {
	f := admin.RuleForm{}
	if err := util.DefaultGetValidParams(ctx, &f); err != nil {
		response.Error(ctx, err, nil)
		return
	}

	flag := c.service.DeleteRule(f.Name)
	response.SuccessOrError(ctx, flag, "success", "fail")
}
